package com.seari.custody.filter;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.seari.custody.util.JwtTokenUtils;
import com.seari.custody.constant.MessageConstant;
import com.seari.custody.mapper.UserMapper;
import com.seari.custody.pojo.MessageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;

/**
 * JWT鉴权拦截器
 * 登录成功后 走此类进行鉴权操作
 */
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {

    @Autowired
    public UserMapper userMapper;

    public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    /**
     * 在过滤之前和之后执行的事件
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        //不带Token的全部放行  方便部分接口测试
        String tokenHeader = request.getHeader(JwtTokenUtils.TOKEN_HEADER);
        // 如果请求头中没有Authorization信息则直接放行了
        if (tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtils.TOKEN_PREFIX)) {
            chain.doFilter(request, response);
            return;
        }

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse rep = (HttpServletResponse) response;

        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        //含有Bear TOKEN
        String token = request.getHeader(JwtTokenUtils.TOKEN_HEADER);
        //不含有Bear
        String authToken = token.substring("Bearer ".length());

        MessageBean resultInfo = new MessageBean();
        boolean isFilter = false;

        String method = ((HttpServletRequest) request).getMethod();
        if (method.equals("OPTIONS")) {
            rep.setStatus(HttpServletResponse.SC_OK);
        } else {
            if (Strings.isNullOrEmpty(token)) {
                resultInfo.setCode(MessageConstant.UN_AUTHORIZED);
                resultInfo.setMessage("用户授权认证没有通过!客户端请求参数中无token信息");
            } else {
                //是否放行  方便测试全部放行
                isFilter = true;
//                if (HandlerNullUtils.objectIsNull(GuavaCacheUtil.get(authToken))) {
//                    resultInfo.setCode(MessageConstant.UN_AUTHORIZED);
//                    resultInfo.setMessage("用户授权认证没有通过!客户端请求参数token信息无效或该用户未登录");
//                } else {
//                    if (!JwtTokenUtils.isExpiration(authToken)) {
//                        isFilter = true;
//                    } else {
//                        resultInfo.setCode(MessageConstant.UN_AUTHORIZED);
//                        resultInfo.setMessage("用户授权认证没有通过!客户端请求参数token已过期");
//                    }
//                }
            }
        }
        // 验证失败
        if (MessageConstant.UN_AUTHORIZED.equalsIgnoreCase(resultInfo.getCode())) {
            try (OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream(),
                    StandardCharsets.UTF_8); PrintWriter writer = new PrintWriter(osw, true)) {

                String jsonStr = JSON.toJSONString(resultInfo);
                writer.write(jsonStr);
                writer.flush();
            } catch (Exception e) {
                logger.error("过滤器返回信息失败:" + e.getMessage(), e);
            }
            return;
        }

        if (isFilter) {
            // 若请求头中有token 则调用下面的方法进行解析 并设置认证信息
            SecurityContextHolder.getContext().setAuthentication(getAuthentication(token));
            super.doFilterInternal(request, response, chain);
        }
    }


    /**
     * 从token中获取用户信息并新建一个token
     *
     * @param tokenHeader 字符串形式的Token请求头
     * @return 带用户名和密码以及权限的Authentication
     */
    private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader) {
        // 去掉前缀 获取Token字符串
        String token = tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX, "");
        // 从Token中解密获取用户名

        String userNumber = JwtTokenUtils.getUserNumber(token);
        // 从Token中解密获取用户角色
//        String role = JwtTokenUtils.getUserRole(token);
//        // 将[ROLE_XXX,ROLE_YYY]格式的角色字符串转换为数组
//        String[] roles = StringUtils.strip(role, "[]").split(", ");
        Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
//        for (String s:roles)
//        {
//            authorities.add(new SimpleGrantedAuthority(s));
//        }
        if (userNumber != null) {
            return new UsernamePasswordAuthenticationToken(userNumber, null, authorities);
        }
        return null;
    }
}
